<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    /*
    * 适配器模式：
    *   将一个类的接口转换成客户希望的另外一个接口，使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
    *   使用一个已经存在的对象，但是其方法或属性接口不符合我们的要求，所以需要对其进行适配。
    *   例如：usb接口转换器
    *
    * 适配器的原则：
    *   不能影响原来的功能，也就是不能修改原来旧接口的代码
    *   原来的功能要拿过来，在原来的基础上再去进行相关的适配和调整
    *
    * 优点：简单，复用性比较高
    * 缺点：系统的层级复杂，会包装许多函数
    *
    * */

    //香港版插头
    class Plug{
        fn(){
            return "香港的插头"
        }
    }

    //适配插头
    class Target{
        constructor() { //旧的接口不能丢也不能修改
            this.plug = new Plug() //这里是旧的接口：香港版插头
        }
        adaptePlug(){ //这里就是进行适配，将旧的接口与新的接口进行适配
            return this.plug.fn() + "转换器转成中国内地版插头" //这里面写如何适配，适配的内容
        }
    }
    let gn = new Target() //new一个适配器
    gn.adaptePlug() //适配器调用适配后的接口


    //1.用适配器保证传入参数的完整性与顺序性：
    function doThing(name,title,age,color,size,flg){ //这个参数很多，万一传漏了或者传错位置就不好
        //执行的操作
    }

    //我们要的结果是，哪怕我们的数据位置不一样，用适配器也能保证参数不出问题
    var obj = { //这是我们需要接收的数据
        name:"remi",
        title:"500w",
        age:18,
        color:"yellow",
        size:180,
        flg:"xiaomubiao"
    }

    //适配器
    function adaptDoThing(obj){

        //默认的数据，如果没传或者漏传就用默认的参数数据
        var _adapt = {
            name:"xx",
            title:"xx",
            age:0,
            color:"xx",
            size:0,
            flg:"xx"
        }

        //这才是真正的适配
        for(var i in _adapt){
            obj[i] = obj[i] || _adapt[i] //用一个for in循环，实参要么等于形参（传了），要么等于默认的参数（没传）
        }

        doThing(obj.name,obj.title,obj.age,obj.color,obj.size,obj.flg) //此时我们对传入的参数进行适配，使其位置与原来的一一对应
    }

    adaptDoThing(obj)


    //2.适配器用于参数类型转换
    //例如现在我们得到的一个数据是数组形式
    var arr = []
    arr.id = 1
    arr.name = "remi"
    arr.dex = "xxxx"

    function arrToObj(arr){ //适配器函数，数组转对象形式
        return {
            id:arr[0],
            name:arr[1],
            des:arr[2]
        }
    }
    var obj = arrToObj(arr)
    obj.id //这时候我们就能得到对象形式的数据
    obj.des //这时候我们就能得到对象形式的数据


    //3.适配器用于代码兼容
    //有些浏览器是用new XMLHttpRequest()创建ajax对象，有些浏览器是用ActiveXObject("Microsoft.XMLHTTP")创建ajax对象
    function XMLHTTP(){
        if(window.ActiveXObject){ //如果兼容这个则返回这个创建ajax
            return ActiveXObject("Microsoft.XMLHTTP")
        }else{ //否则返回这个创建ajax
            return new XMLHttpRequest()
        }
    }
    XMLHTTP() //创建ajax对象
</script>
</body>
</html>